package org.jsbd.boss.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.jsbd.boss.bto.AppInfo;
import org.jsbd.boss.bto.BatteryInfo;
import org.jsbd.boss.bto.HttpResult;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.domian.IpRange;
import org.jsbd.boss.domian.WifiInfo;
import org.jsbd.boss.domian.channel.CameraInfo;
import org.jsbd.boss.domian.channel.SdkClientInfo;
import org.jsbd.boss.service.ClientManager;
import org.jsbd.boss.service.ICameraService;
import org.jsbd.boss.service.IWifiInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @desc
 * @Date 2018/10/26 09:22
 * @Author xupengcheng [xupengcheng@zhexinit.com]
 */
public class NewUserClientUtil {

    public static final Logger LOGGER = LoggerFactory.getLogger(NewUserClientUtil.class);


    private static  byte[] downLoadFile(String fileName, String imsi){
        byte[] bytes = new byte[0];
        try {
            bytes = OssUtils.downloadWebmengFile(fileName);
        } catch (Exception e) {
            LOGGER.warn("没有对应文件 {} {}", imsi, fileName);

        }
        return bytes;
    }

    public static SdkClientInfo checkClient(HttpResult httpResult, RedisClient redisClient, IpRange ipRange) throws Exception {
        String imsi = httpResult.getImsi();
        String hsman = httpResult.getHsman();
        String hstype = httpResult.getHstype();
        SdkClientInfo sdkClientInfo = new SdkClientInfo();
        String sdkUuid = "sdkFile/" + httpResult.getUuid();
        String isExist = CacheKey.FILE_UPLOAD_FINISH_KEY + httpResult.getUuid();
        Object fileExists = redisClient.get(isExist);
        if (fileExists == null) {
            LOGGER.warn("文件信息没有传输完全 {} {}", imsi, sdkUuid);
            return null;
        }
        byte[] buildProp = downLoadFile(sdkUuid + "/build.prop", imsi);
        byte[] getProp = downLoadFile(sdkUuid + "/getprop", imsi);
        byte[] boot_id = downLoadFile(sdkUuid + "/boot_id", imsi);
        byte[] cpuinfo = downLoadFile(sdkUuid + "/cpuinfo", imsi);
        byte[] meminfo = downLoadFile(sdkUuid + "/meminfo", imsi);
        byte[] pcm = downLoadFile(sdkUuid + "/pcm", imsi);
        byte[] newSo = new byte[0];
        try {
            newSo = OssUtils.downloadWebmengFile(sdkUuid + "/newSo");
        } catch (Exception e) {
            LOGGER.warn("新用户参数校验失败2 没有so文件 {} {} {} {}", new String[]{imsi, hsman, hstype, sdkUuid});
            return null;
        }
        Map<String, String> propertiesMap = PropertiesUtil.getPropertiesMap(new String(getProp, "utf-8"));
        Map<String, String> meminfoMap = PropertiesUtil.getPropertiesMap(new String(meminfo, "utf-8"));
        String[] keys = propertiesMap.keySet().toArray(new String[0]);
        for (String key : keys) {
            String value = propertiesMap.get(key);
            propertiesMap.remove(key);
            String newkey = key.replace("[", "").replace("]", "");
            if (StringUtils.isNotBlank(value)) {
                value = value.replace("[", "").replace("]", "");
                propertiesMap.put(newkey, value);
            }
        }
        if (meminfoMap != null) {
            propertiesMap.putAll(meminfoMap);
        }

        //校验参数
        if (!checkSdkClient(httpResult, ipRange, sdkClientInfo, propertiesMap)) {
            LOGGER.warn("新用户参数校验失败3 {} {} {} {}", new String[]{imsi, hsman, hstype, sdkUuid});
            return null;
        }
        sdkClientInfo.setBuild_prop(Base64.encodeBase64String(buildProp));
        sdkClientInfo.setGet_prop(Base64.encodeBase64String(getProp));
        sdkClientInfo.setBoot_id(Base64.encodeBase64String(boot_id));
        sdkClientInfo.setCpuinfo(Base64.encodeBase64String(cpuinfo));
        sdkClientInfo.setMeminfo(Base64.encodeBase64String(meminfo));
        sdkClientInfo.setPcm(Base64.encodeBase64String(pcm));
        sdkClientInfo.setCtestInfo(Base64.encodeBase64String(newSo));
        String kernelVersion = httpResult.getKernelVersion();
        if (StringUtils.isNotBlank(kernelVersion)) {
            sdkClientInfo.setKernel_info(Base64.encodeBase64String(kernelVersion.getBytes()));
        }
        String arpInfo = httpResult.getArpInfo();
        if (StringUtils.isNotBlank(arpInfo)) {
            sdkClientInfo.setNet_arp(Base64.encodeBase64String(arpInfo.getBytes()));
        }
        return sdkClientInfo;
    }



    private static boolean checkSdkClient(HttpResult httpResult, IpRange ipRange, SdkClientInfo client, Map<String, String> propMap) {
        ICameraService cameraService = SpringContextUtils.getBean(ICameraService.class);
        CameraInfo cameraInfo = cameraService.selectCamera(httpResult.getHsman(), httpResult.getHstype());
        if (cameraInfo == null) {
            cameraInfo = cameraService.selectRandomCamera(httpResult.getHsman(), httpResult.getHstype());
        }
        client.setCameraInfo(cameraInfo.getContent());
        client.setSdcard_id(getStringValue(httpResult.getSd_id()));
        client.setPhoneType(getIntValue(httpResult.getNetworkSystem()));
        client.setNetworkType(getIntValue(httpResult.getNetworkType()));
        client.setImsi(httpResult.getImsi());
        client.setNetworkOperator(getStringValue(httpResult.getNetworkOperator()));
        client.setImei(getStringValue(httpResult.getImei()));
        client.setSimOperator(getStringValue(httpResult.getSimOperatorName()));
        client.setNetworkOperatorName(getStringValue(httpResult.getNetworkOperatorName()));
        AppInfo appInfo = SpringContextUtils.getBean(ClientManager.class).initClientAppName(httpResult.getAppInfo(), httpResult.getHsman(), httpResult.getHstype());
        client.setUser_app(appInfo.getApp_name());
        client.setSystem_app(appInfo.getSystem_app_name());
        client.setWidthPixels(getIntValue(httpResult.getScreenWidth()));
        client.setHeightPixels(getIntValue(httpResult.getScreenHeight()));
        client.setNet(getStringValue(httpResult.getNetInterfaces()));

        if (httpResult.getDensityDpi() != null) {
            client.setDensityDpi(httpResult.getDensityDpi().intValue());
        } else {
            client.setDensityDpi(0);
        }
        Double xdpi = httpResult.getXdpi();
        if (xdpi != null) {
            client.setXdpi(xdpi);
        } else {
            client.setXdpi(0D);
        }

        Double ydpi = httpResult.getYdpi();
        if (ydpi != null) {
            client.setYdpi(ydpi);
        } else {
            client.setYdpi(0D);
        }


        client.setDensity(getDoubleValue(httpResult.getDensity()));
        client.setIccid(getStringValue(httpResult.getICCID()));
        client.setMac(getStringValue(httpResult.getMac()));
        String wifiInfo = httpResult.getReserved3();
        if (StringUtils.isBlank(wifiInfo)) {
            WifiInfo wifi = new WifiInfo();
            wifi.setIpCity(ipRange.getCityId());
            wifi.setIpProvince(ipRange.getProvinceId());
            wifi = SpringContextUtils.getBean(IWifiInfoService.class).findRandomWifiInfo(wifi);
            if (wifi == null) {
                LOGGER.warn("imsi cannot get wifi {}", httpResult.getImsi());
                return false;
            } else {
                client.setWifiInfo(wifi.getWifiInfo());
            }
        } else {
            client.setWifiInfo(wifiInfo);
        }

        String userAgent = httpResult.getUserAgent();
        if (StringUtils.isNotBlank(userAgent)) {
            try {
                JSONArray agents = JSONArray.parseArray(userAgent);
                if (agents != null && agents.size() > 0) {
                    client.setUserAgent(agents.get(0).toString());
                } else {
                    client.setUserAgent("");
                }
            } catch (Exception e) {
                LOGGER.warn("useragent 解析错误 {} {}", httpResult.getImsi(), httpResult.getUuid());
                client.setUserAgent(userAgent);
            }
        } else {
            client.setUserAgent("");
        }
        client.setSensorInfo(getStringValue(httpResult.getSensorInfo()));
        client.setLongitude(getDoubleValue(httpResult.getLongitude()));
        client.setLatitude(getDoubleValue(httpResult.getLatitude()));
        client.setLac(getIntValue(httpResult.getLac()));
        client.setCid(getIntValue(httpResult.getCellId()));

        String networkExtraInfo = httpResult.getNetworkExtraInfo();
        client.setNetworkExtraInfo(getStringValue(networkExtraInfo));
        if (StringUtils.isNotBlank(networkExtraInfo)) {
            client.setSsid(networkExtraInfo);
        }
        if (StringUtils.isNotBlank(wifiInfo)) {
            String[] split = wifiInfo.split("\\|");
            String[] split1 = split[0].split(";");
            if (split1.length == 3) {
                client.setBssid(split1[0]);
                client.setSsid(split1[2]);
            } else {
                client.setBssid(split1[0]);
            }
        }
        client.setMaxMemory(httpResult.getRuntimeMaxMemory());
        client.setSystemSharedLibraryNames(httpResult.getSystemSharedLibraryNames());
        client.setSystemAvailableFeatures(httpResult.getSystemAvailableFeatures());

        String visitIp = httpResult.getVisitIp();
        if (StringUtils.isNotBlank(visitIp)) {
            client.setLocal_ip(IpUtil.inetAddressToInt(visitIp));
        }
        client.setBuildId(getStringValue(httpResult.getBuildId()));
        client.setBuildRadioVersion(getStringValue(httpResult.getRadioVersion()));
        client.setBoard(getStringValue(httpResult.getBoard()));
        client.setDevice(getStringValue(httpResult.getProductDevice()));
        client.setManufacturer(getStringValue(httpResult.getHsman()));
        client.setImei2(getStringValue(httpResult.getImei2()));
        client.setBuildType(getStringValue(httpResult.getBuildType()));
        client.setBuildTags(getStringValue(httpResult.getBuildTags()));
        client.setFingerPrint(getStringValue(httpResult.getFingerprint()));
        client.setBuildVersionIncremental(getStringValue(httpResult.getBuildVersionIncremental()));
        client.setBuildCodeName(getStringValue(httpResult.getBuildVersionCodename()));
        client.setModel(getStringValue(httpResult.getHstype()));

        if (StringUtils.isNotBlank(httpResult.getOsVer())) {
            String[] osVers = httpResult.getOsVer().split("_");
            if (osVers.length == 1) {
                client.setVersion_release(osVers[0]);
            } else {
                client.setVersion_release(osVers[1]);
            }
        } else {
            client.setVersion_release("");
        }
        client.setBrand(getStringValue(httpResult.getBRAND()));
        client.setVersion_sdk(getStringValue(httpResult.getBuildVersionSdk()));
        client.setSdk_int(getIntValue(httpResult.getBuild_version()));
        client.setBootloader(getStringValue(httpResult.getBootloader()));
        client.setProduct(getStringValue(httpResult.getProductName()));
        client.setHardware(getStringValue(httpResult.getHardware()));
        String spaceInfo = httpResult.getSpaceInfo();
        if (StringUtils.isNotBlank(spaceInfo)) {
            JSONObject jsonObject = JSONObject.parseObject(spaceInfo);
            client.setBlockCount(jsonObject.getInteger("blockCount"));
            client.setBlockSize(jsonObject.getInteger("blockSize"));
            client.setAvailableBlocks(jsonObject.getInteger("availableBlocks"));
        } else {
            client.setBlockCount(0);
            client.setBlockSize(0);
            client.setAvailableBlocks(0);
        }
        client.setLanguage(getStringValue(httpResult.getLanguage()));
        client.setCpu_abi(getStringValue(httpResult.getCpu_abi()));
        client.setCpu_abi2(getStringValue(httpResult.getCpu_abi2()));
        client.setDisplay(getStringValue(httpResult.getDisplay()));

        Integer networkInfoType = httpResult.getNetworkInfoType();
        if (networkInfoType != null) {
            client.setNetworkSubType(networkInfoType);
        } else {
            client.setNetworkSubType(0);
        }

        Integer phoneNetworkType = httpResult.getPhoneNetworkType();

        if (phoneNetworkType != null) {
            client.setPhoneNetworkType(phoneNetworkType);
        } else {
            client.setPhoneNetworkType(0);
        }


        int buildVersion = getIntValue(httpResult.getBuild_version());
        String mac = httpResult.getMac();
        String bht_mac = httpResult.getBht_mac();
        if (buildVersion >= 23) {
            if (StringUtils.isBlank(bht_mac) || (StringUtils.isNotBlank(mac) && mac.equals(bht_mac))) {
                client.setBuletoothMac("02:00:00:00:00:00");
            } else {
                client.setBuletoothMac(bht_mac);
            }
        } else {
            if (StringUtils.isNotBlank(mac) && mac.equals(bht_mac)) {
                client.setBuletoothMac(MacUtil.getMacAddrWithFormat(":"));
            } else {
                client.setBuletoothMac(bht_mac);
            }
        }


        Long buildTime = httpResult.getBuildTime();
        if (buildTime != null) {
            client.setBuild_time(buildTime);

        } else {
            client.setBuild_time(0L);
        }

        client.setSerial(getStringValue(httpResult.getSerialno()));
        BatteryInfo batteryInfo = httpResult.getBatteryInfo();
        if (batteryInfo == null) {
            batteryInfo = new BatteryInfo();
        }
        client.setPlugged(getIntValue(batteryInfo.getPlugged()));
        client.setScale(getIntValue(batteryInfo.getScale()));
        client.setStatus(getIntValue(batteryInfo.getStatus()));
        client.setHealth(getIntValue(batteryInfo.getHealth()));
        client.setLevel(getIntValue(batteryInfo.getLevel()));
        client.setPresent(batteryInfo.getPresent());
        client.setTechnology(getStringValue(batteryInfo.getTechnology()));
        client.setVoltage(getIntValue(batteryInfo.getVoltage()));
        client.setTemperature(getIntValue(batteryInfo.getTemperature()));
        client.setAndroidId(getStringValue(httpResult.getAndroidId()));
        //ro 文件 对应getprop
        client.setRo_serialno(getStringValue(propMap.get("ro.serialno")));
        client.setRo_product_model(getStringValue(propMap.get("ro.product.model")));
        client.setRo_product_brand(getStringValue(propMap.get("ro.product.brand")));
        client.setRo_debuggable(getStringValue(propMap.get("ro.debuggable")));
        client.setRo_secure(getStringValue(propMap.get("ro.secure")));
        client.setRo_build_version_release(getStringValue(propMap.get("ro.build.version.release")));
        client.setRo_build_version_sdk(getStringValue(propMap.get("ro.build.version.sdk")));
        client.setRo_build_display_id(getStringValue(propMap.get("ro.build.display.id")));
        client.setRo_boot_bootloader(getStringValue(propMap.get("ro.boot.bootloader")));
        client.setRo_product_board(getStringValue(propMap.get("ro.product.board")));
        client.setRo_product_device(getStringValue(propMap.get("ro.product.device")));
        client.setRo_product_name(getStringValue(propMap.get("ro.product.name")));
        client.setRo_product_manufacturer(getStringValue(propMap.get("ro.product.manufacturer")));
        client.setRo_boot_hardware(getStringValue(propMap.get("ro.boot.hardware")));
        client.setRo_boot_baseband(getStringValue(propMap.get("ro.boot.baseband")));
        client.setRo_kernel_qemu(getStringValue(propMap.get("ro.kernel.qemu")));
        client.setRo_build_date_utc(getStringValue(propMap.get("ro.build.date.utc")));
        client.setRo_boot_serialno(getStringValue(propMap.get("ro.boot.serialno")));
        client.setPersist_sys_country(getStringValue(propMap.get("persist.sys.country")));
        client.setPersist_sys_language(getStringValue(propMap.get("persist.sys.language")));
        client.setRo_build_tags(getStringValue(propMap.get("ro.build.tags")));
        client.setRo_product_cpu_abi2(getStringValue(propMap.get("ro.product.cpu.abi2")));
        client.setRo_build_type(getStringValue(propMap.get("ro.build.type")));
        client.setRo_build_fingerprint(getStringValue(propMap.get("ro.build.fingerprint")));
        client.setRo_product_cpu_abi(getStringValue(propMap.get("ro.product.cpu.abi")));
        client.setGsm_sim_state(getStringValue(propMap.get("gsm.sim.state")));
        client.setGsm_network_type(getStringValue(propMap.get("gsm.network.type")));
        client.setSys_usb_state(getStringValue(propMap.get("sys.usb.state")));
        client.setNet_hostname(getStringValue(propMap.get("net.hostname")));
        client.setNet_dns1(getStringValue(propMap.get("net.dns1")));
        client.setMemAvailable(getMemLongValue(getStringValue(propMap.get("MemAvailable"))));
        client.setMemTotal(getMemLongValue(getStringValue(propMap.get("MemTotal"))));
        client.setMemFree(getMemLongValue(getStringValue(propMap.get("MemFree"))));
        client.setRo_carrier(getStringValue(propMap.get("ro.carrier")));
        client.setRo_hardware(getStringValue(propMap.get("ro.hardware")));
        client.setRo_build_version_security_patch(getStringValue(propMap.get("ro.build.version.security_patch")));
        client.setRo_build_host(getStringValue(propMap.get("ro.build.host")));
        client.setAllCellInfo(getStringValue(httpResult.getAllCellInfo()));
        client.setSimOperatorName(getStringValue(httpResult.getSimOperatorName()));
        client.setMiui_build(getStringValue(httpResult.getMiuiOsBuildInfo()));
        client.setCodecs(getStringValue(httpResult.getCodecs()));
        client.setMmc_blocks(getStringValue(httpResult.getMmcBlocks()));
        client.setInternal_content(getStringValue(httpResult.getInternalContent()));
        client.setExternal_content(getStringValue(httpResult.getExternalContent()));
        client.setRo_miui_ui_version_name(getStringValue(propMap.get("ro_miui_ui_version_name")));
        client.setRo_build_version_emui(getStringValue(propMap.get("ro_build_version_emui")));
        client.setRo_build_version_opporom(getStringValue(propMap.get("ro_build_version_opporom")));
        client.setRo_vivo_os_build_display_id(getStringValue(propMap.get("ro_vivo_os_build_display_id")));
        client.setRo_vivo_product_version(getStringValue(propMap.get("ro.vivo.product.version")));
        client.setPsContent(getStringValue(httpResult.getPsContent()));
        client.setRo_build_id(getStringValue(propMap.get("ro.build.id")));
        client.setRo_build_version_incremental(propMap.get("ro.build.version.incremental"));
        client.setPersist_service_bdroid_bdaddr(propMap.get("persist.service.bdroid.bdaddr"));

        JSONObject jsonObject = JSONObject.parseObject(httpResult.getSpecialProperties());
        if(jsonObject != null){
            client.setSpecial_props(httpResult.getSpecialProperties());
            client.setAndroid_icu_cldr_version(jsonObject.getString("androidIcuCldrVersion"));
            client.setAndroid_icu_library_version(jsonObject.getString("androidIcuLibraryVersion"));
            client.setAndroid_openssl_version(jsonObject.getString("androidOpensslVersion"));
            client.setAndroid_zlib_version(jsonObject.getString("androidZlibVersion"));
            client.setJavaVMName(jsonObject.getString("javaVmName"));
            client.setJavaVMVersion(jsonObject.getString("javaVmVersion"));
            client.setJavaRuntimeName(jsonObject.getString("javaRuntimeName"));
            client.setJavaRuntimeVersion(jsonObject.getString("javaRuntimeVersion"));
        }
        client.setFileTimes(getStringValue(httpResult.getFileTimes()));
        client.setFileMask(getStringValue(httpResult.getFileMask()));
        client.setUname(getStringValue(httpResult.getUname()));
        client.setRo_miui_ui_version_code(getStringValue(propMap.get("ro.miui.ui.version.code")));
        client.setRo_miui_internal_storage(getStringValue(propMap.get("ro.miui.internal.storage")));
        client.setRo_build_hw_emu_emui_api_level(getStringValue(propMap.get("ro.build.hw_emu_emui_api_level")));
        client.setRo_vivo_os_name(getStringValue(propMap.get("ro.vivo.os.name")));
        client.setRo_vivo_os_version(getStringValue(propMap.get("ro.vivo.os.version")));
        client.setRo_rom_different_version(getStringValue(propMap.get("ro.rom.different.version")));
        client.setRo_product_cpu_abilist(getStringValue(propMap.get("ro.product.cpu.abilist")));
        return true;
    }


    private static long getMemLongValue(String value) {
        //1318908 kB
        if (StringUtils.isNotBlank(value)) {
            String[] split = value.split(" ");
            return Long.parseLong(split[0]);
        } else {
            return 0L;
        }
    }

    private static String getStringValue(String value) {
        if (StringUtils.isBlank(value) || "null".equals(value)) {
            return "";
        } else {
            return value;
        }
    }

    private static int getIntValue(String value) {
        if (StringUtils.isBlank(value) || "null".equals(value)) {
            return 0;
        } else {
            return Integer.parseInt(value);
        }
    }

    private static int getIntValue(Integer value) {
        if (value == null) {
            return 0;
        } else {
            return value;
        }
    }

    private static double getDoubleValue(String value) {
        if (StringUtils.isBlank(value) || "null".equals(value)) {
            return 0;
        } else {
            return Double.parseDouble(value);
        }
    }

}
